package com.zzk.jpmvvmbase.base

import androidx.databinding.ViewDataBinding

/**
 * 传统方式的懒加载
 * 以前处理 Fragment 的懒加载，我们通常会在 Fragment 中处理 setUserVisibleHint + onHiddenChanged 这两个函数，
 * 而在 Androidx 模式下，我们可以使用 FragmentTransaction.setMaxLifecycle() 的方式来处理 Fragment 的懒加载
 *
 * @ProjectName:    JetPackMVVMBase
 * @Package:        com.zzk.jpmvvmbase.base
 * @ClassName:      TraditionalLazyBaseFragment
 * @Description:
 * @Author:         brilliantzhao
 * @CreateDate:     2021.1.30 9:03
 * @UpdateUser:
 * @UpdateDate:     2021.1.30 9:03
 * @UpdateRemark:
 * @Version:        1.0.0
 */
abstract class TraditionalLazyBaseFragment<VM : BaseViewModel, DB : ViewDataBinding> :
    BaseFragment<VM, DB>() {

    //##########################  custom variables start ##########################################

    /**
     * 是否执行懒加载
     */
    private var isLoaded = false

    /**
     * 当前Fragment是否对用户可见
     */
    private var isVisibleToUser = false

    /**
     * 因为当使用ViewPager+Fragment形式会调用该方法时，setUserVisibleHint会优先Fragment生命周期函数调用，
     * 所以这个时候就,会导致在setUserVisibleHint方法执行时就执行了懒加载，
     * 而不是在onResume方法实际调用的时候执行懒加载。所以需要这个变量
     */
    private var isCallResume = false

    /**
     * 是否调用了setUserVisibleHint方法。处理show+add+hide模式下，默认可见 Fragment 不调用
     * onHiddenChanged 方法，进而不执行懒加载方法的问题。
     */
    private var isCallUserVisibleHint = false

    //##########################  custom variables end  ###########################################

    //##########################  override custom metohds start ###################################

    override fun onResume() {
        super.onResume()
        isCallResume = true
        if (!isCallUserVisibleHint) isVisibleToUser = !isHidden
        judgeLazyInit()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        isLoaded = false
        isVisibleToUser = false
        isCallUserVisibleHint = false
        isCallResume = false
    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        isVisibleToUser = !hidden
        judgeLazyInit()
    }

    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        this.isVisibleToUser = isVisibleToUser
        isCallUserVisibleHint = true
        judgeLazyInit()
    }

    //##########################  override custom metohds end  ####################################

    //##########################  override third methods start ####################################

    /**
     * 懒加载
     */
    abstract fun lazyLoadData()

    //##########################  override third methods end  #####################################

    //##########################  custom metohds start     ########################################

    private fun judgeLazyInit() {
        if (!isLoaded && isVisibleToUser && isCallResume) {
            lazyLoadData()
            isLoaded = true
        }
    }

    //##########################  custom metohds end   ############################################

}